package com.infore.dataAudit.service.impl;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ManagementService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.infore.dataAudit.enums.ResultStatus;
import com.infore.dataAudit.service.RunningTimeService;
import com.infore.dataAudit.service.task.ExportActivitiHisProcess;
import com.infore.dataAudit.util.ResultEntity;







/**
 * 流程实例运行相关接口实现类
 * 
 * @author cys
 */
@Service("runningTimeService")
public class RunningTimeServiceImpl implements RunningTimeService {
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private IdentityService identityService;
    @Resource
    private ManagementService managementService;
    @Resource
    private RepositoryService repositoryService;
    @Autowired
    private ProcessEngineFactoryBean processEngine;
    @Resource
    private HistoryService historyService;
    @Resource
    private FormService formService;
    
    
    
    @Override
    public ResultEntity startProcess(String key, Map<String, Object> param) {
        return startProcess(key, null, param);
    }

    @Override
    public ResultEntity startProcess(String key, String businessKey, Map<String, Object> param) {
       return startProcess(key, businessKey, null, param);
    }

    @Override
    public ResultEntity stopProcessByKey(String key, String reason) throws ActivitiObjectNotFoundException {
        runtimeService.deleteProcessInstance(key, reason);
        return new ResultEntity(ResultStatus.SUCCESS, "流程停止成功");
    }

    @Override
    public ResultEntity suspendProcess(String processInstanceId) {
        try {
            runtimeService.suspendProcessInstanceById(processInstanceId);
            return new ResultEntity(ResultStatus.SUCCESS, "流程挂起成功");
        } catch (ActivitiObjectNotFoundException e) {
            e.printStackTrace();
            return new ResultEntity(ResultStatus.ERROR, "流程实例未找到");
        }
    }

    @Override
    public ResultEntity activeProcess(String processInstanceId) {
        try {
            runtimeService.activateProcessInstanceById(processInstanceId);
            return new ResultEntity(ResultStatus.SUCCESS, "流程激活成功");
        } catch (ActivitiObjectNotFoundException e) {
            e.printStackTrace();
            return new ResultEntity(ResultStatus.ERROR, "流程实例未找到");
        }
    }

    @Override
    public InputStream generateDiagram(String processInstanceId) {
        Command<InputStream> cmd = new ExportActivitiHisProcess(processInstanceId, runtimeService, repositoryService,
                processEngine, historyService);
        return managementService.executeCommand(cmd);
    }

    @Override
    public InputStream generateDiagramByDeployKey(String deployKey) {
        ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService
                .createProcessDefinitionQuery().processDefinitionKey(deployKey).latestVersion().singleResult();
        if (processDefinition == null) {
            return null;
        }
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
        ProcessEngineConfigurationImpl config = processEngine.getProcessEngineConfiguration();
        Context.setProcessEngineConfiguration(processEngine.getProcessEngineConfiguration());

        List<String> activeActivityIds = new ArrayList<String>();
        /**
         * 配置文件中设置字体
         */
        InputStream imageStream = new DefaultProcessDiagramGenerator().generateDiagram(bpmnModel, "png",
                activeActivityIds, new ArrayList<String>(), config.getActivityFontName(), config.getLabelFontName(),
                config.getAnnotationFontName(), config.getClassLoader(), 1.0);

        return imageStream;
    }

    @Override
    public ResultEntity startProcess(String key, String businessKey, String authenticatedUserId,
            Map<String, Object> param) {
        try {
            ProcessInstance instance = null;
            identityService.setAuthenticatedUserId(authenticatedUserId);
            if (businessKey == null || businessKey.trim().isEmpty()) {
                instance = runtimeService.startProcessInstanceByKey(key, param);
            } else {
                instance = runtimeService.startProcessInstanceByKey(key, businessKey, param);
            }
            return new ResultEntity(ResultStatus.SUCCESS, "流程开始成功",instance.getId());
        } catch (ActivitiObjectNotFoundException e) {
            e.printStackTrace();
            return new ResultEntity(ResultStatus.ERROR, "流程开始失败");
        }finally {
            identityService.setAuthenticatedUserId(null);
        }
    }}
